In [1]:
import os
import tensorflow as tf
import keras.backend.tensorflow_backend as KTF

def get_session(gpu_fraction=0.3):
    '''Assume that you have 6GB of GPU memory and want to allocate ~2GB'''

    num_threads = os.environ.get('OMP_NUM_THREADS')
    gpu_options = tf.GPUOptions(per_process_gpu_memory_fraction=gpu_fraction)

    if num_threads:
        return tf.Session(config=tf.ConfigProto(
            gpu_options=gpu_options, intra_op_parallelism_threads=num_threads))
    else:
        return tf.Session(config=tf.ConfigProto(gpu_options=gpu_options))

get_session()


Using TensorFlow backend.
Out[1]:
<tensorflow.python.client.session.Session at 0x7f314d9f4cc0>

In [1]:
import argparse
import collections
import datetime
import enum
import glob
import logging
import numpy as np
import os
import random
import sys
import tempfile
import tensorflow as tf

import keras.backend.tensorflow_backend as KTF
from keras.applications.imagenet_utils import preprocess_input
from keras.applications.resnet50 import ResNet50
from keras.callbacks import ModelCheckpoint
from keras.models import Sequential                              
from keras.layers import Dense, Dropout, Flatten, Input, Reshape            
from keras.preprocessing import image

import pelops.const as const
from pelops.datasets.dgcars import DGCarsDataset
from pelops.utils import SetType, setup_custom_logger


Using TensorFlow backend.

In [2]:
batch_size = 194
img_height = 224
img_width = 224
img_dimension = 3

train_dir_path = "./datasets/train/" 
val_dir_path = "./datasets/test/"
train_features_path = None
val_features_path = None
dataset_type = "DGCarsDataset"
conv_model_type = "ResNet50"
conv_model_name = "ResNet50"

1. Extract Features


In [4]:
np.zeros((1,3 ))


Out[4]:
array([[ 0.,  0.,  0.]])

In [5]:
"""
    while True:
        xs = []
        ys = []
        for filename1, filename2 in zip(image_list[0::2], image_list[1::2]):
            print("filename: {}".format(filename))
            x1 = load_image(filename1)
            x2 = load_image(filename2)
            x = np.concatenate((x1, x2), axis=0)
            xs.append(x)
            # if batch_size is greater than one, append more x into xs
            print("x.shape: {}".format(x.shape))
            y1 = np.zeros((1, num_classes))
            y1[0][train_image_class_mapping[filename1]] = 1
            y2 = np.zeros((1, num_classes))
            y2[0][train_image_class_mapping[filename2]] = 1
            y = np.concatenate((y1, y2), axis=0)
            ys.append(y)
            # if batch_size is greater than one, append more y into ys
            print("y.shape: {}".format(y.shape))
        yield (np.array(xs).squeeze(), np.array(ys))
"""


Out[5]:
'\n    while True:\n        xs = []\n        ys = []\n        for filename1, filename2 in zip(image_list[0::2], image_list[1::2]):\n            print("filename: {}".format(filename))\n            x1 = load_image(filename1)\n            x2 = load_image(filename2)\n            x = np.concatenate((x1, x2), axis=0)\n            xs.append(x)\n            # if batch_size is greater than one, append more x into xs\n            print("x.shape: {}".format(x.shape))\n            y1 = np.zeros((1, num_classes))\n            y1[0][train_image_class_mapping[filename1]] = 1\n            y2 = np.zeros((1, num_classes))\n            y2[0][train_image_class_mapping[filename2]] = 1\n            y = np.concatenate((y1, y2), axis=0)\n            ys.append(y)\n            # if batch_size is greater than one, append more y into ys\n            print("y.shape: {}".format(y.shape))\n        yield (np.array(xs).squeeze(), np.array(ys))\n'

In [65]:
# load data 

def load_image(img_path):
    img = image.load_img(img_path, target_size=(img_height, img_width))
    x = image.img_to_array(img)
    x = np.expand_dims(x, axis=0)
    x = preprocess_input(x)
    return x
    
def image_class_generator(train_image_classes_mapping, num_classes, batch_size):
    image_list = list(train_image_class_mapping.keys())
    print("len(image_list): {}".format(len(image_list)))
    
    while True:
        xs = []
        ys = []
        for filename in image_list:
            #print("filename: {}".format(filename))
            x = load_image(filename)
            xs.append(x)
            # if batch_size is greater than one, append more x into xs
            #print("x.shape: {}".format(x.shape))
            y = np.zeros(num_classes)
            y[train_image_class_mapping[filename]] = 1
            ys.append(y)
            # if batch_size is greater than one, append more y into ys
            #print("y.shape: {}".format(y.shape))
        yield (np.array(xs).squeeze(), np.array(ys))
    
train_image_classes = set()
train_image_class_mapping = {}

for image_class_filepath in glob.glob(os.path.join(train_dir_path, '*')):
    if os.path.isdir(image_class_filepath):
        #print("image_class_filepath: {}".format(image_class_filepath))
        image_class_num = int(os.path.basename(image_class_filepath)) - 1
        #print("image_class_num: {}".format(image_class_num))
        train_image_classes.add(image_class_num)
        for filename in glob.glob(os.path.join(image_class_filepath, '*')):
            #print("train_image_class_mapping[{}] = {}".format(filename, image_class_num))
            train_image_class_mapping[filename] = image_class_num

nb_classes = len(train_image_classes)
print("len(train_image_classes): {}".format(nb_classes))

train_generator = image_class_generator(train_image_class_mapping, len(train_image_classes), batch_size)

count = 0
for i in train_generator:
    x, y = i
    count = count + 1
    print("count: {}, x.shape: {}, y.shape: {}".format(count, x.shape, y.shape))
    break

    
# x.shape == (194, 224, 224, 3)
# y.shape == (194, 3)


len(train_image_classes): 3
len(image_list): 194
count: 1, x.shape: (194, 224, 224, 3), y.shape: (194, 3)

In [91]:
val_image_classes = set()
val_image_class_mapping = {}

for image_class_filepath in glob.glob(os.path.join(val_dir_path, '*')):
    if os.path.isdir(image_class_filepath):
        #print("image_class_filepath: {}".format(image_class_filepath))
        image_class_num = int(os.path.basename(image_class_filepath)) - 1
        #print("image_class_num: {}".format(image_class_num))
        val_image_classes.add(image_class_num)
        for filename in glob.glob(os.path.join(image_class_filepath, '*')):
            #print("train_image_class_mapping[{}] = {}".format(filename, image_class_num))
            val_image_class_mapping[filename] = image_class_num

print("len(train_image_classes): {}".format(len(val_image_classes)))

val_generator = image_class_generator(val_image_class_mapping, len(val_image_classes), batch_size)


len(train_image_classes): 3

In [93]:
model = ResNet50(
            include_top=False,
            weights="imagenet",
            input_tensor=Input(
                shape=(
                    img_height, 
                    img_width, 
                    img_dimension
                )
            )
        )

In [94]:
for layer in model.layers:
    layer.trainable = False

In [96]:
def __extract_features(generator, model, batch_size, set_type):
    feature_dirpath = "./features/"
    print("create a feature directory to store saved features: {}".format(feature_dirpath))
    if not os.path.exists(feature_dirpath):
        os.makedirs(feature_dirpath)

    print("extract features from convolutional model based on data")
    print("generator: {}_generator".format(set_type))
    print("batch_size: {}".format(batch_size))
    features = model.predict_generator(
        generator,
        batch_size
    )

    time_now = datetime.datetime.now().strftime("%Y%m%d_%H_%M_%S")
    features_filepath = feature_dirpath + "TESTING_{}_{}_{}_features_{}.npy".format(
        dataset_type,
        conv_model_type,
        set_type,
        time_now
    )
    print("save features to {}".format(features_filepath))
    np.save(open(features_filepath, "wb"), features)

    return features, features_filepath

In [13]:
train_features, train_features_path = __extract_features(train_generator, model, batch_size, "train")


create a feature directory to store saved features: ./features/
extract features from convolutional model based on data
generator: train_generator
batch_size: 194
save features to ./features/TESTING_DGCarsDataset_ResNet50_train_features_20170214_20_43_52.npy

In [79]:
#save features to ./features/TESTING_DGCarsDataset_ResNet50_train_features_20170214_20_12_10.npy
#save features to ./features/TESTING_DGCarsDataset_ResNet50_train_features_20170214_20_39_50.npy
#save features to ./features/TESTING_DGCarsDataset_ResNet50_train_features_20170214_20_43_52.npy

In [3]:
train_feature_path = "./features/TESTING_DGCarsDataset_ResNet50_train_features_20170214_20_39_50.npy"
train_features = np.load(open(train_feature_path, "rb"))

2. Train classifier based on features


In [4]:
len(train_features)


Out[4]:
194

In [5]:
train_features.shape


Out[5]:
(194, 1, 1, 2048)

In [100]:
count = 0
for i in train_generator:
    x, y = i
    count = count + 1
    print("count: {}, x.shape: {}, y.shape: {}".format(count, x.shape, y.shape))
    break

print(y.shape)
labels = y
print(labels.shape)


count: 1, x.shape: (194, 224, 224, 3), y.shape: (194, 3)
(194, 3)
(194, 3)

In [43]:
"""
def __create_generator_from_features(features, labels):
    for feature, label in zip(features, labels):
        yield (feature, label)

train_features_generator = __create_generator_from_features(train_features, labels)
"""

In [44]:
"""
count = 0
for i in train_features_generator:
    x, y = i
    count = count + 1
    print("count: {}, x.shape: {}, y.shape: {}".format(count, x.shape, y.shape))
"""


count: 1, x.shape: (1, 1, 2048), y.shape: (3,)
count: 2, x.shape: (1, 1, 2048), y.shape: (3,)
count: 3, x.shape: (1, 1, 2048), y.shape: (3,)
count: 4, x.shape: (1, 1, 2048), y.shape: (3,)
count: 5, x.shape: (1, 1, 2048), y.shape: (3,)
count: 6, x.shape: (1, 1, 2048), y.shape: (3,)
count: 7, x.shape: (1, 1, 2048), y.shape: (3,)
count: 8, x.shape: (1, 1, 2048), y.shape: (3,)
count: 9, x.shape: (1, 1, 2048), y.shape: (3,)
count: 10, x.shape: (1, 1, 2048), y.shape: (3,)
count: 11, x.shape: (1, 1, 2048), y.shape: (3,)
count: 12, x.shape: (1, 1, 2048), y.shape: (3,)
count: 13, x.shape: (1, 1, 2048), y.shape: (3,)
count: 14, x.shape: (1, 1, 2048), y.shape: (3,)
count: 15, x.shape: (1, 1, 2048), y.shape: (3,)
count: 16, x.shape: (1, 1, 2048), y.shape: (3,)
count: 17, x.shape: (1, 1, 2048), y.shape: (3,)
count: 18, x.shape: (1, 1, 2048), y.shape: (3,)
count: 19, x.shape: (1, 1, 2048), y.shape: (3,)
count: 20, x.shape: (1, 1, 2048), y.shape: (3,)
count: 21, x.shape: (1, 1, 2048), y.shape: (3,)
count: 22, x.shape: (1, 1, 2048), y.shape: (3,)
count: 23, x.shape: (1, 1, 2048), y.shape: (3,)
count: 24, x.shape: (1, 1, 2048), y.shape: (3,)
count: 25, x.shape: (1, 1, 2048), y.shape: (3,)
count: 26, x.shape: (1, 1, 2048), y.shape: (3,)
count: 27, x.shape: (1, 1, 2048), y.shape: (3,)
count: 28, x.shape: (1, 1, 2048), y.shape: (3,)
count: 29, x.shape: (1, 1, 2048), y.shape: (3,)
count: 30, x.shape: (1, 1, 2048), y.shape: (3,)
count: 31, x.shape: (1, 1, 2048), y.shape: (3,)
count: 32, x.shape: (1, 1, 2048), y.shape: (3,)
count: 33, x.shape: (1, 1, 2048), y.shape: (3,)
count: 34, x.shape: (1, 1, 2048), y.shape: (3,)
count: 35, x.shape: (1, 1, 2048), y.shape: (3,)
count: 36, x.shape: (1, 1, 2048), y.shape: (3,)
count: 37, x.shape: (1, 1, 2048), y.shape: (3,)
count: 38, x.shape: (1, 1, 2048), y.shape: (3,)
count: 39, x.shape: (1, 1, 2048), y.shape: (3,)
count: 40, x.shape: (1, 1, 2048), y.shape: (3,)
count: 41, x.shape: (1, 1, 2048), y.shape: (3,)
count: 42, x.shape: (1, 1, 2048), y.shape: (3,)
count: 43, x.shape: (1, 1, 2048), y.shape: (3,)
count: 44, x.shape: (1, 1, 2048), y.shape: (3,)
count: 45, x.shape: (1, 1, 2048), y.shape: (3,)
count: 46, x.shape: (1, 1, 2048), y.shape: (3,)
count: 47, x.shape: (1, 1, 2048), y.shape: (3,)
count: 48, x.shape: (1, 1, 2048), y.shape: (3,)
count: 49, x.shape: (1, 1, 2048), y.shape: (3,)
count: 50, x.shape: (1, 1, 2048), y.shape: (3,)
count: 51, x.shape: (1, 1, 2048), y.shape: (3,)
count: 52, x.shape: (1, 1, 2048), y.shape: (3,)
count: 53, x.shape: (1, 1, 2048), y.shape: (3,)
count: 54, x.shape: (1, 1, 2048), y.shape: (3,)
count: 55, x.shape: (1, 1, 2048), y.shape: (3,)
count: 56, x.shape: (1, 1, 2048), y.shape: (3,)
count: 57, x.shape: (1, 1, 2048), y.shape: (3,)
count: 58, x.shape: (1, 1, 2048), y.shape: (3,)
count: 59, x.shape: (1, 1, 2048), y.shape: (3,)
count: 60, x.shape: (1, 1, 2048), y.shape: (3,)
count: 61, x.shape: (1, 1, 2048), y.shape: (3,)
count: 62, x.shape: (1, 1, 2048), y.shape: (3,)
count: 63, x.shape: (1, 1, 2048), y.shape: (3,)
count: 64, x.shape: (1, 1, 2048), y.shape: (3,)
count: 65, x.shape: (1, 1, 2048), y.shape: (3,)
count: 66, x.shape: (1, 1, 2048), y.shape: (3,)
count: 67, x.shape: (1, 1, 2048), y.shape: (3,)
count: 68, x.shape: (1, 1, 2048), y.shape: (3,)
count: 69, x.shape: (1, 1, 2048), y.shape: (3,)
count: 70, x.shape: (1, 1, 2048), y.shape: (3,)
count: 71, x.shape: (1, 1, 2048), y.shape: (3,)
count: 72, x.shape: (1, 1, 2048), y.shape: (3,)
count: 73, x.shape: (1, 1, 2048), y.shape: (3,)
count: 74, x.shape: (1, 1, 2048), y.shape: (3,)
count: 75, x.shape: (1, 1, 2048), y.shape: (3,)
count: 76, x.shape: (1, 1, 2048), y.shape: (3,)
count: 77, x.shape: (1, 1, 2048), y.shape: (3,)
count: 78, x.shape: (1, 1, 2048), y.shape: (3,)
count: 79, x.shape: (1, 1, 2048), y.shape: (3,)
count: 80, x.shape: (1, 1, 2048), y.shape: (3,)
count: 81, x.shape: (1, 1, 2048), y.shape: (3,)
count: 82, x.shape: (1, 1, 2048), y.shape: (3,)
count: 83, x.shape: (1, 1, 2048), y.shape: (3,)
count: 84, x.shape: (1, 1, 2048), y.shape: (3,)
count: 85, x.shape: (1, 1, 2048), y.shape: (3,)
count: 86, x.shape: (1, 1, 2048), y.shape: (3,)
count: 87, x.shape: (1, 1, 2048), y.shape: (3,)
count: 88, x.shape: (1, 1, 2048), y.shape: (3,)
count: 89, x.shape: (1, 1, 2048), y.shape: (3,)
count: 90, x.shape: (1, 1, 2048), y.shape: (3,)
count: 91, x.shape: (1, 1, 2048), y.shape: (3,)
count: 92, x.shape: (1, 1, 2048), y.shape: (3,)
count: 93, x.shape: (1, 1, 2048), y.shape: (3,)
count: 94, x.shape: (1, 1, 2048), y.shape: (3,)
count: 95, x.shape: (1, 1, 2048), y.shape: (3,)
count: 96, x.shape: (1, 1, 2048), y.shape: (3,)
count: 97, x.shape: (1, 1, 2048), y.shape: (3,)
count: 98, x.shape: (1, 1, 2048), y.shape: (3,)
count: 99, x.shape: (1, 1, 2048), y.shape: (3,)
count: 100, x.shape: (1, 1, 2048), y.shape: (3,)
count: 101, x.shape: (1, 1, 2048), y.shape: (3,)
count: 102, x.shape: (1, 1, 2048), y.shape: (3,)
count: 103, x.shape: (1, 1, 2048), y.shape: (3,)
count: 104, x.shape: (1, 1, 2048), y.shape: (3,)
count: 105, x.shape: (1, 1, 2048), y.shape: (3,)
count: 106, x.shape: (1, 1, 2048), y.shape: (3,)
count: 107, x.shape: (1, 1, 2048), y.shape: (3,)
count: 108, x.shape: (1, 1, 2048), y.shape: (3,)
count: 109, x.shape: (1, 1, 2048), y.shape: (3,)
count: 110, x.shape: (1, 1, 2048), y.shape: (3,)
count: 111, x.shape: (1, 1, 2048), y.shape: (3,)
count: 112, x.shape: (1, 1, 2048), y.shape: (3,)
count: 113, x.shape: (1, 1, 2048), y.shape: (3,)
count: 114, x.shape: (1, 1, 2048), y.shape: (3,)
count: 115, x.shape: (1, 1, 2048), y.shape: (3,)
count: 116, x.shape: (1, 1, 2048), y.shape: (3,)
count: 117, x.shape: (1, 1, 2048), y.shape: (3,)
count: 118, x.shape: (1, 1, 2048), y.shape: (3,)
count: 119, x.shape: (1, 1, 2048), y.shape: (3,)
count: 120, x.shape: (1, 1, 2048), y.shape: (3,)
count: 121, x.shape: (1, 1, 2048), y.shape: (3,)
count: 122, x.shape: (1, 1, 2048), y.shape: (3,)
count: 123, x.shape: (1, 1, 2048), y.shape: (3,)
count: 124, x.shape: (1, 1, 2048), y.shape: (3,)
count: 125, x.shape: (1, 1, 2048), y.shape: (3,)
count: 126, x.shape: (1, 1, 2048), y.shape: (3,)
count: 127, x.shape: (1, 1, 2048), y.shape: (3,)
count: 128, x.shape: (1, 1, 2048), y.shape: (3,)
count: 129, x.shape: (1, 1, 2048), y.shape: (3,)
count: 130, x.shape: (1, 1, 2048), y.shape: (3,)
count: 131, x.shape: (1, 1, 2048), y.shape: (3,)
count: 132, x.shape: (1, 1, 2048), y.shape: (3,)
count: 133, x.shape: (1, 1, 2048), y.shape: (3,)
count: 134, x.shape: (1, 1, 2048), y.shape: (3,)
count: 135, x.shape: (1, 1, 2048), y.shape: (3,)
count: 136, x.shape: (1, 1, 2048), y.shape: (3,)
count: 137, x.shape: (1, 1, 2048), y.shape: (3,)
count: 138, x.shape: (1, 1, 2048), y.shape: (3,)
count: 139, x.shape: (1, 1, 2048), y.shape: (3,)
count: 140, x.shape: (1, 1, 2048), y.shape: (3,)
count: 141, x.shape: (1, 1, 2048), y.shape: (3,)
count: 142, x.shape: (1, 1, 2048), y.shape: (3,)
count: 143, x.shape: (1, 1, 2048), y.shape: (3,)
count: 144, x.shape: (1, 1, 2048), y.shape: (3,)
count: 145, x.shape: (1, 1, 2048), y.shape: (3,)
count: 146, x.shape: (1, 1, 2048), y.shape: (3,)
count: 147, x.shape: (1, 1, 2048), y.shape: (3,)
count: 148, x.shape: (1, 1, 2048), y.shape: (3,)
count: 149, x.shape: (1, 1, 2048), y.shape: (3,)
count: 150, x.shape: (1, 1, 2048), y.shape: (3,)
count: 151, x.shape: (1, 1, 2048), y.shape: (3,)
count: 152, x.shape: (1, 1, 2048), y.shape: (3,)
count: 153, x.shape: (1, 1, 2048), y.shape: (3,)
count: 154, x.shape: (1, 1, 2048), y.shape: (3,)
count: 155, x.shape: (1, 1, 2048), y.shape: (3,)
count: 156, x.shape: (1, 1, 2048), y.shape: (3,)
count: 157, x.shape: (1, 1, 2048), y.shape: (3,)
count: 158, x.shape: (1, 1, 2048), y.shape: (3,)
count: 159, x.shape: (1, 1, 2048), y.shape: (3,)
count: 160, x.shape: (1, 1, 2048), y.shape: (3,)
count: 161, x.shape: (1, 1, 2048), y.shape: (3,)
count: 162, x.shape: (1, 1, 2048), y.shape: (3,)
count: 163, x.shape: (1, 1, 2048), y.shape: (3,)
count: 164, x.shape: (1, 1, 2048), y.shape: (3,)
count: 165, x.shape: (1, 1, 2048), y.shape: (3,)
count: 166, x.shape: (1, 1, 2048), y.shape: (3,)
count: 167, x.shape: (1, 1, 2048), y.shape: (3,)
count: 168, x.shape: (1, 1, 2048), y.shape: (3,)
count: 169, x.shape: (1, 1, 2048), y.shape: (3,)
count: 170, x.shape: (1, 1, 2048), y.shape: (3,)
count: 171, x.shape: (1, 1, 2048), y.shape: (3,)
count: 172, x.shape: (1, 1, 2048), y.shape: (3,)
count: 173, x.shape: (1, 1, 2048), y.shape: (3,)
count: 174, x.shape: (1, 1, 2048), y.shape: (3,)
count: 175, x.shape: (1, 1, 2048), y.shape: (3,)
count: 176, x.shape: (1, 1, 2048), y.shape: (3,)
count: 177, x.shape: (1, 1, 2048), y.shape: (3,)
count: 178, x.shape: (1, 1, 2048), y.shape: (3,)
count: 179, x.shape: (1, 1, 2048), y.shape: (3,)
count: 180, x.shape: (1, 1, 2048), y.shape: (3,)
count: 181, x.shape: (1, 1, 2048), y.shape: (3,)
count: 182, x.shape: (1, 1, 2048), y.shape: (3,)
count: 183, x.shape: (1, 1, 2048), y.shape: (3,)
count: 184, x.shape: (1, 1, 2048), y.shape: (3,)
count: 185, x.shape: (1, 1, 2048), y.shape: (3,)
count: 186, x.shape: (1, 1, 2048), y.shape: (3,)
count: 187, x.shape: (1, 1, 2048), y.shape: (3,)
count: 188, x.shape: (1, 1, 2048), y.shape: (3,)
count: 189, x.shape: (1, 1, 2048), y.shape: (3,)
count: 190, x.shape: (1, 1, 2048), y.shape: (3,)
count: 191, x.shape: (1, 1, 2048), y.shape: (3,)
count: 192, x.shape: (1, 1, 2048), y.shape: (3,)
count: 193, x.shape: (1, 1, 2048), y.shape: (3,)
count: 194, x.shape: (1, 1, 2048), y.shape: (3,)

In [45]:
checkpoint_dirpath = "./checkpoints/"
print("create a checkpoint directory to store saved checkpoints: {}".format(checkpoint_dirpath))
if not os.path.exists(checkpoint_dirpath):
    os.makedirs(checkpoint_dirpath)

checkpoint_filepath = \
    checkpoint_dirpath + \
    "{}_{}_features_".format(dataset_type, "classifier") + \
    "{epoch:02d}_{val_acc:.2f}.npy"

checkpoint = ModelCheckpoint(
    checkpoint_filepath, 
    monitor="val_acc", 
    save_best_only=True, 
    mode="max"
)
callbacks_list = [checkpoint]


create a checkpoint directory to store saved checkpoints: ./checkpoints/

In [46]:
nb_features = model.output_shape[-1] # same as train_features.shape[-1]
nb_hidden_layers = int(round(np.mean([nb_features, nb_classes])))
print("{} -> [hidden layer {}] -> {}\n".format(nb_features, nb_hidden_layers, nb_classes))


top_model = Sequential()
top_model.add(Dense(nb_hidden_layers, activation="relu", input_shape=train_features.shape[1:]))
top_model.add(Flatten())
top_model.add(Dense(nb_classes, activation="softmax")) 

"""
top_model = Sequential()
top_model = Dense(nb_hidden_layers, activation="relu", input_shape=train_features.shape[1:])(top_model)
top_model = Flatten()(top_model)
top_model = Dense(nb_classes, activation="softmax")(top_model)
"""


2048 -> [hidden layer 1026] -> 3


In [47]:
top_model.compile(
    loss="categorical_crossentropy",
    optimizer="adam",
    metrics=["accuracy"]
)

In [68]:
print("train_features.shape: {}".format(train_features.shape))
print("labels.shape: {}".format(y.shape))

top_model.fit(
    x=train_features,
    y=labels
)


train_features.shape: (194, 1, 1, 2048)
labels.shape: (194, 3)
Epoch 1/10
194/194 [==============================] - 0s - loss: 3.4334 - acc: 0.3144     
Epoch 2/10
194/194 [==============================] - 0s - loss: 1.5317 - acc: 0.4845     
Epoch 3/10
194/194 [==============================] - 0s - loss: 0.8931 - acc: 0.5825     
Epoch 4/10
194/194 [==============================] - 0s - loss: 0.7575 - acc: 0.6959     
Epoch 5/10
194/194 [==============================] - 0s - loss: 0.6201 - acc: 0.7577     
Epoch 6/10
194/194 [==============================] - 0s - loss: 0.5320 - acc: 0.8144     
Epoch 7/10
194/194 [==============================] - 0s - loss: 0.4709 - acc: 0.8454     
Epoch 8/10
194/194 [==============================] - 0s - loss: 0.4747 - acc: 0.8351     
Epoch 9/10
194/194 [==============================] - ETA: 0s - loss: 0.3090 - acc: 0.9500 - 0s - loss: 0.3010 - acc: 0.9536     
Epoch 10/10
194/194 [==============================] - 0s - loss: 0.2913 - acc: 0.9588     
Out[68]:
<keras.callbacks.History at 0x7f7124dac080>

In [102]:
val_features, val_features_path = __extract_features(val_generator, model, batch_size, "train")

print(val_features.shape)
print(labels.shape)

score = top_model.evaluate(
    x=val_features,
    y=labels,
    batch_size=batch_size,
)

print("{}: {}".format(
    top_model.metrics_names[1],
    score[1]
))


create a feature directory to store saved features: ./features/
extract features from convolutional model based on data
generator: train_generator
batch_size: 194
save features to ./features/TESTING_DGCarsDataset_ResNet50_train_features_20170214_23_14_12.npy
(194, 1, 1, 2048)
(194, 3)
194/194 [==============================] - 0s
acc: 0.3865979313850403

3. Train entire model with data


In [77]:
from keras.models import Model                              

model = ResNet50(
            include_top=False,
            weights="imagenet",
            input_tensor=Input(
                shape=(
                    img_height, 
                    img_width, 
                    img_dimension
                )
            )
        )

for layer in model.layers:
    layer.trainable = True

In [80]:
combined_model = Model(input=model.input, output=top_model(model.output))

In [82]:
combined_model.compile(
    loss="categorical_crossentropy",
    optimizer="adam",
    metrics=["accuracy"]
)

In [104]:
count = 0
for i in train_generator:
    x, y = i
    count = count + 1
    print("count: {}, x.shape: {}, y.shape: {}".format(count, x.shape, y.shape))
    break

print("x.shape: {}, y.shape: {}".format(x.shape, y.shape))


count: 1, x.shape: (194, 224, 224, 3), y.shape: (194, 3)
x.shape: (194, 224, 224, 3), y.shape: (194, 3)

In [90]:
combined_model.fit(
    x=x,
    y=y
)


Epoch 1/10
194/194 [==============================] - 2s - loss: 1.6541 - acc: 0.4845     
Epoch 2/10
194/194 [==============================] - 2s - loss: 0.8336 - acc: 0.6753     
Epoch 3/10
194/194 [==============================] - 2s - loss: 0.4715 - acc: 0.8144     
Epoch 4/10
194/194 [==============================] - 2s - loss: 0.9739 - acc: 0.7268     
Epoch 5/10
194/194 [==============================] - 2s - loss: 0.9672 - acc: 0.7010     
Epoch 6/10
194/194 [==============================] - 2s - loss: 0.9624 - acc: 0.6340     
Epoch 7/10
194/194 [==============================] - 2s - loss: 0.7284 - acc: 0.7887     
Epoch 8/10
194/194 [==============================] - 2s - loss: 0.5870 - acc: 0.7526     
Epoch 9/10
194/194 [==============================] - 2s - loss: 0.4786 - acc: 0.8454     
Epoch 10/10
194/194 [==============================] - 2s - loss: 0.4721 - acc: 0.8505     
Out[90]:
<keras.callbacks.History at 0x7f6ee4a03400>

In [105]:
score = combined_model.evaluate(
    x=x,
    y=y,
    batch_size=batch_size,
)

print("{}: {}".format(
    combined_model.metrics_names[1],
    score[1]
))


194/194 [==============================] - 3s
acc: 0.3865979313850403

In [ ]: